package com.zenithmind.article.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.article.feign.UserFeignClient;
import com.zenithmind.article.mapper.ArticleMapper;
import com.zenithmind.article.mapper.ArticleTagMapper;
import com.zenithmind.article.mapper.CategoryMapper;
import com.zenithmind.article.mapper.TagMapper;
import com.zenithmind.article.pojo.domain.*;
import com.zenithmind.article.pojo.query.ArticleQuery;
import com.zenithmind.article.pojo.vo.ArticleVO;
import com.zenithmind.article.pojo.vo.UserVO;
import com.zenithmind.article.service.ArticleService;
import com.zenithmind.common.result.PageResult;
import com.zenithmind.common.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.zenithmind.common.exception.BusinessException;
import com.zenithmind.common.annotation.DataCache;
import com.zenithmind.common.annotation.DataCacheEvict;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 文章服务实现
 * 遵循单一职责原则：专注于文章核心业务逻辑
 * 遵循依赖倒置原则：通过构造器注入依赖
 */
@Slf4j
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {
    
    private final ArticleTagMapper articleTagMapper;
    private final CategoryMapper categoryMapper;
    private final UserFeignClient userFeignClient;
    private final TagMapper tagMapper;

    // 缓存前缀常量
    private static final String CACHE_ARTICLE_PREFIX = "article";
    private static final String CACHE_ARTICLE_LIST_PREFIX = "article:list";

    // 构造器注入，遵循依赖倒置原则
    public ArticleServiceImpl(
            ArticleTagMapper articleTagMapper,
            CategoryMapper categoryMapper,
            UserFeignClient userFeignClient,
            TagMapper tagMapper) {
        this.articleTagMapper = articleTagMapper;
        this.categoryMapper = categoryMapper;
        this.userFeignClient = userFeignClient;
        this.tagMapper = tagMapper;
    }

    @Override
    @Transactional
    @DataCacheEvict(prefix = CACHE_ARTICLE_PREFIX, key = "#article.id")
    public Article addOrUpdateArticle(Article article) {
        log.info("新增或更新文章: {}", article.getTitle());
        
        if (article.getId() == null) {
            save(article);
        } else {
            updateById(article);
        }
        return article;
    }

    @Override
    @DataCache(prefix = CACHE_ARTICLE_LIST_PREFIX, key = "'page' + #articleQuery.current")
    public PageResult<ArticleVO> pageArticle(ArticleQuery articleQuery) {
        Page<Article> page = articleQuery.toPage();
        
        Page<Article> articlePage = lambdaQuery()
                .like(StringUtils.isNotBlank(articleQuery.getTitle()), Article::getTitle, articleQuery.getTitle())
                .eq(articleQuery.getStatus() != null, Article::getStatusCode, articleQuery.getStatus())
                .eq(StringUtils.isNotBlank(articleQuery.getCategoryId()), Article::getCategoryId, articleQuery.getCategoryId())
                .eq(StringUtils.isNotBlank(articleQuery.getUserId()), Article::getUserId, articleQuery.getUserId())
                .eq(articleQuery.getIsTop() != null, Article::getIsTop, articleQuery.getIsTop())
                .eq(articleQuery.getIsRecommend() != null, Article::getIsRecommend, articleQuery.getIsRecommend())
                .orderByDesc(Article::getCreateTime)
                .page(page);

        List<Article> articles = articlePage.getRecords();
        if (articles.isEmpty()) {
            return new PageResult<>(Collections.emptyList(), articlePage.getTotal(), 
                                  articlePage.getCurrent(), articlePage.getSize());
        }

        List<ArticleVO> articleVOs = articles.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());

        return new PageResult<>(articleVOs, articlePage.getTotal(), 
                              articlePage.getCurrent(), articlePage.getSize());
    }

    @Override
    @DataCache(prefix = CACHE_ARTICLE_PREFIX, key = "#id")
    public ArticleVO getArticleById(String id) {
        log.info("获取文章详情: {}", id);
        
        Article article = getById(id);
        if (article == null) {
            throw new BusinessException("文章不存在");
        }

        return convertToVO(article);
    }

    @Override
    @Transactional
    public Boolean publishArticle(String id) {
        log.info("发布文章: {}", id);
        
        Article article = getById(id);
        if (article == null) {
            throw new BusinessException("文章不存在");
        }

        article.publish();
        updateById(article);
        return true;
    }

    @Override
    @Transactional
    public Boolean unpublishArticle(String id) {
        log.info("下架文章: {}", id);
        
        Article article = getById(id);
        if (article == null) {
            throw new BusinessException("文章不存在");
        }

        article.unpublish();
        updateById(article);
        return true;
    }

    @Override
    @Transactional
    public Boolean updateArticleStatus(String id, String status) {
        log.info("更新文章状态: {}, 状态: {}", id, status);
        
        Article article = getById(id);
        if (article == null) {
            throw new BusinessException("文章不存在");
        }

        switch (status.toLowerCase()) {
            case "publish":
                article.publish();
                break;
            case "unpublish":
                article.unpublish();
                break;
            case "delete":
                article.delete();
                break;
            case "archive":
                article.archive();
                break;
            default:
                throw new BusinessException("不支持的状态: " + status);
        }

        updateById(article);
        return true;
    }

    @Override
    public Long getArticleCountByUserId() {
        return count();
    }

    @Override
    public Long countView() {
        // 使用原生查询统计总浏览量
        List<Article> articles = list();
        return articles.stream()
                .mapToLong(Article::getViewCount)
                .sum();
    }

    private ArticleVO convertToVO(Article article) {
        ArticleVO articleVO = new ArticleVO();
        BeanUtils.copyProperties(article, articleVO);
        
        articleVO.setStatus(article.getStatusCode());
        
        try {
            Result<UserVO> userResult = userFeignClient.getUserById(article.getUserId());
            if (userResult != null && userResult.isSuccess() && userResult.getData() != null) {
                articleVO.setUserVo(userResult.getData());
            }
        } catch (Exception e) {
            log.warn("获取用户信息失败: {}", article.getUserId(), e);
        }

        if (StringUtils.isNotBlank(article.getCategoryId())) {
            Category category = categoryMapper.selectById(article.getCategoryId());
            articleVO.setCategory(category);
        }

        List<Tag> tags = getArticleTags(article.getId());
        articleVO.setTag(tags);

        return articleVO;
    }

    private List<Tag> getArticleTags(String articleId) {
        List<ArticleTag> articleTags = articleTagMapper.selectList(
                new LambdaQueryWrapper<ArticleTag>()
                        .eq(ArticleTag::getArticleId, articleId)
                        .eq(ArticleTag::getStatusCode, 1)
        );

        if (articleTags.isEmpty()) {
            return Collections.emptyList();
        }

        List<String> tagIds = articleTags.stream()
                .map(ArticleTag::getTagId)
                .collect(Collectors.toList());

        return tagMapper.selectBatchIds(tagIds);
    }
}
